﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Drawing.Text;

namespace Walson.Form.Common
{
    public partial class Battery : Control
    {

        private int _Value=50;
        public int Value
        {
            get
            {
                return _Value;
            }
            set
            {
                if (_Value != value)
                {
                    if (value > 100)
                        value = 100;
                    
                    _Value = value;
                    this.Invalidate();
                }
            }
        }


        private int _ThresholdWarnning = 30;
        public int ThresholdWarnning
        {
            get
            {
                return _ThresholdWarnning;
            }
            set
            {
                if (_ThresholdWarnning != value)
                {
                    if (value > 100)
                        value = 100;

                    _ThresholdWarnning = value;
                    this.Invalidate();
                }
            }
        }

        private int _ThresholdAlarm = 10;
        public int ThresholdAlarm
        {
            get
            {
                return _ThresholdAlarm;
            }
            set
            {
                if (_ThresholdAlarm != value)
                {
                    if (value > 100)
                        value = 100;

                    _ThresholdAlarm = value;
                    this.Invalidate();
                }
            }
        }

        private Orientation _Orientation = Orientation.Horizontal;
        public Orientation Orientation
        {
            get
            {
                return _Orientation;
               
            }
            set
            {
                if (_Orientation != value)
                {
                    _Orientation = value;
                    this.Invalidate();
                }
            }
        }

        private Color _BorderColor = Color.White;
        public Color BorderColor
        {
            get
            {
                return _BorderColor;
            }
            set
            {
                if (_BorderColor != value)
                {
                    _BorderColor = value;
                    this.Invalidate();
                }
            }
        }

        private Color[] _InnerColorNormal = new Color[] { Color.Green, Color.Green };
        public Color[] InnerColorNormal
        {
            get
            {
                return _InnerColorNormal;
            }
            set
            {
                if (_InnerColorNormal != value)
                {
                    _InnerColorNormal = value;
                    _FullNormalGradientPosition = new float[value.Length];
                    for (int i = 0; i < _FullNormalGradientPosition.Length; i++)
                    {
                        _FullNormalGradientPosition[i] = (float)i / ((float)_FullNormalGradientPosition.Length - 1f);
                    }
                    this.Invalidate();
                }
            }
        }

        private Color[] _InnerColorWarnning = new Color[] { Color.Yellow, Color.Yellow };
        public Color[] InnerColorWarnning
        {
            get
            {
                return _InnerColorWarnning;
            }
            set
            {
                if (_InnerColorWarnning != value)
                {
                    _InnerColorWarnning = value;
                    _FullWarnningGradientPosition = new float[value.Length];
                    for (int i = 0; i < _FullWarnningGradientPosition.Length; i++)
                    {
                        _FullWarnningGradientPosition[i] = (float)i / ((float)_FullWarnningGradientPosition.Length - 1f);
                    }
                    this.Invalidate();
                }
            }
        }

        private Color[] _InnerColorAlarm = new Color[] { Color.Red, Color.Red };
        public Color[] InnerColorAlarm
        {
            get
            {
                return _InnerColorAlarm;
            }
            set
            {
                if (_InnerColorAlarm != value)
                {
                    _InnerColorAlarm = value;
                    _FullAlarmGradientPosition = new float[value.Length];
                    for (int i = 0; i < _FullAlarmGradientPosition.Length; i++)
                    {
                        _FullAlarmGradientPosition[i] = (float)i / ((float)_FullAlarmGradientPosition.Length - 1f);
                    }
                    this.Invalidate();
                }
            }
        }

        private Color[] _EmptyColor = new Color[] { Color.LightGray, Color.LightGray };
        public Color[] EmptyColor
        {
            get
            {
                return _EmptyColor;
            }
            set
            {
                if (_EmptyColor != value)
                {
                    _EmptyColor = value;

                    _EmptyGradientPosition = new float[value.Length];
                    for (int i = 1; i < _EmptyGradientPosition.Length; i++)
                    {
                        _EmptyGradientPosition[i] = (float)i / ((float)_EmptyGradientPosition.Length - 1f);
                    }
                    this.Invalidate();
                }
            }
        }

        private float[] _FullNormalGradientPosition = new float[] { 0f, 1f };
        public float[] FullNormalGradientPosition
        {
            get
            {
                return _FullNormalGradientPosition;
            }
            set
            {
                if (value.Length != _InnerColorNormal.Length)
                {
//                     if (this.IsInDesignMode())
//                         MessageBox.Show("渐变色位置数量与颜色个数不同。");
                    return;
                }

                if (_FullNormalGradientPosition != value)
                {
                    _FullNormalGradientPosition = value;
                    this.Invalidate();
                }
            }
        }

        private float[] _FullWarnningGradientPosition = new float[] { 0f, 1f };
        public float[] FullWarnningGradientPosition
        {
            get
            {
                return _FullWarnningGradientPosition;
            }
            set
            {
                if (value.Length != _InnerColorWarnning.Length)
                {
//                     if (this.IsInDesignMode())
//                         MessageBox.Show("渐变色位置数量与颜色个数不同。");
                    return;
                }

                if (_FullWarnningGradientPosition != value)
                {
                    _FullWarnningGradientPosition = value;
                    this.Invalidate();
                }
            }
        }

        private float[] _FullAlarmGradientPosition = new float[] { 0f, 1f };
        public float[] FullAlarmGradientPosition
        {
            get
            {
                return _FullAlarmGradientPosition;
            }
            set
            {
                if (value.Length != _InnerColorAlarm.Length)
                {
//                     if (this.IsInDesignMode())
//                         MessageBox.Show("渐变色位置数量与颜色个数不同。");
                    return;
                }

                if (_FullAlarmGradientPosition != value)
                {
                    _FullAlarmGradientPosition = value;
                    this.Invalidate();
                }
            }
        }

        private float[] _EmptyGradientPosition = new float[] { 0f, 1f };
        public float[] EmptyGradientPosition
        {
            get
            {
                return _EmptyGradientPosition;
            }
            set
            {
                if (value.Length != _EmptyColor.Length)
                {
//                     if (this.IsInDesignMode())
//                         MessageBox.Show("渐变色位置数量与颜色个数不同。");
                    return;
                }

                if (_EmptyGradientPosition != value)
                {
                    _EmptyGradientPosition = value;
                    this.Invalidate();
                }
            }
        }

        private int _CapHeight = 5;
        public int CapHeight
        {
            get
            {
                return _CapHeight;
            }
            set
            {
                if (_CapHeight != value)
                {
                    _CapHeight = value;
                    this.Invalidate();
                }
            }
        }

        private Color _BackColor = Color.Transparent;
        public Color BackColor
        {
            get
            {
                return _BackColor;
            }
            set
            {
                if (_BackColor != value)
                {
                    _BackColor = value;
                    this.Invalidate();
                }
            }
        }

        private bool IsInDesignMode()
        {
            bool returnFlag = false;

            if (System.ComponentModel.LicenseManager.UsageMode == System.ComponentModel.LicenseUsageMode.Designtime)
            {
                returnFlag = true;
            }
            else if (System.Diagnostics.Process.GetCurrentProcess().ProcessName.ToUpper().Equals("DEVENV"))
            {
                returnFlag = true;
            }

            return returnFlag;
        }

        public Battery()
        {
            InitializeComponent();
            this.DoubleBuffered = true;
        }

        private Bitmap DrawEmptyBattery0(int width, int height)
        {
            if (width == 0 || height == 0)
                return null;

            Bitmap bmp = new Bitmap(width, height);
            {
                using (Graphics g = Graphics.FromImage(bmp))
                {
                    g.SmoothingMode = SmoothingMode.AntiAlias;
                    g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
                    g.Clear(Color.Transparent);

                    float capHeigth = height * 0.05f;
                    if (capHeigth > 20f)
                        capHeigth = 20f;

                    PointF[] borderPoints = new PointF[9];
                    borderPoints[0] = new PointF(1, capHeigth);
                    borderPoints[1] = new PointF(width / 2 - width * 0.2f, capHeigth);
                    borderPoints[2] = new PointF(width / 2 - width * 0.2f, 1);
                    borderPoints[3] = new PointF(width / 2 + width * 0.2f, 1);
                    borderPoints[4] = new PointF(width / 2 + width * 0.2f, capHeigth);
                    borderPoints[5] = new PointF(width - 1, capHeigth);
                    borderPoints[6] = new PointF(width - 1, height - 1);
                    borderPoints[7] = new PointF(1, height - 1);
                    borderPoints[8] = new PointF(1, capHeigth);

                    LinearGradientBrush lgb = new LinearGradientBrush(new Rectangle(0, 30, width, height), Color.Red, Color.White, 0f);

                    ColorBlend blend = new ColorBlend(9);

                    Color[] emptyColor = new Color[]{
                        Color.FromArgb(57,57,57),
                        Color.FromArgb(96,96,96),
                        Color.FromArgb(117,117,117),
                        Color.FromArgb(177,178,178),
                        Color.FromArgb(217,217,217),
                        Color.FromArgb(206,206,206),
                        Color.FromArgb(171,171,171),
                        Color.FromArgb(136,136,136),
                        Color.FromArgb(94,94,94),
                    };

                    Color[] fullColor = new Color[]{
                        Color.FromArgb(0,85,129),
                        Color.FromArgb(0,94,142),
                        Color.FromArgb(0,151,229),
                        Color.FromArgb(85,193,255),
                        Color.FromArgb(180,228,255),
                        Color.FromArgb(180,228,255),
                        Color.FromArgb(1,152,230),
                        Color.FromArgb(0,115,175),
                        Color.FromArgb(0,103,156),
                    };

                    blend.Colors = emptyColor;

                    blend.Positions = new float[] 
                    {
                        0f,
                        0.06f,
                        0.33f,
                        0.51f,
                        0.64f,
                        0.72f,
                        0.87f,
                        0.98f,
                        1f
                    };

                    lgb.InterpolationColors = blend;

                    g.FillRectangle(lgb, new RectangleF(0f, capHeigth, width, height - capHeigth));

                    blend.Colors = fullColor;
                    lgb.InterpolationColors = blend;
                    g.FillRectangle(lgb, new RectangleF(0f, height - (height - capHeigth) * Value / 100f, width, (height - capHeigth) * Value / 100f));

                    g.DrawLines(new Pen(_BorderColor, 2f), borderPoints);
                }
            }
            //bmp.Save(@"c:\a.bmp");
            return bmp;
        }


        private Bitmap DrawEmptyBattery(int width, int height)
        {
            if (width == 0 || height == 0)
                return null;

            Bitmap bmp = new Bitmap(width, height);
            {
                using (Graphics g = Graphics.FromImage(bmp))
                {
                    g.SmoothingMode = SmoothingMode.AntiAlias;
                    g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
                    //g.Clear(Color.Red);

//                     float capHeigth = height * 0.07f;
//                     if (capHeigth > 20f)
//                         capHeigth = 20f;

                    PointF[] borderPoints = new PointF[9];
                    borderPoints[0] = new PointF(0, _CapHeight);
                    borderPoints[1] = new PointF(width / 2 - width * 0.2f, _CapHeight);
                    borderPoints[2] = new PointF(width / 2 - width * 0.2f, 1);
                    borderPoints[3] = new PointF(width / 2 + width * 0.2f, 1);
                    borderPoints[4] = new PointF(width / 2 + width * 0.2f, _CapHeight);
                    borderPoints[5] = new PointF(width - 1, _CapHeight);
                    borderPoints[6] = new PointF(width-1 , height-1);
                    borderPoints[7] = new PointF(0, height-1);
                    borderPoints[8] = new PointF(0, _CapHeight);

                    g.FillRectangle(new SolidBrush(Color.FromArgb(64, 64, 64)), borderPoints[2].X, borderPoints[2].Y, borderPoints[4].X - borderPoints[2].X, borderPoints[4].Y - borderPoints[2].Y);

                    LinearGradientBrush lgb = new LinearGradientBrush(new Rectangle(0, 30, width, height), Color.Red, Color.White, 0f);

                    ColorBlend blend = new ColorBlend(9);

                    // 绘制电池为空的图形
                    blend.Colors = _EmptyColor;

                    blend.Positions = _EmptyGradientPosition;

                    lgb.InterpolationColors = blend;

                    g.FillRectangle(lgb, new RectangleF(0f, _CapHeight, width, height - _CapHeight));

                    // 绘制电池有电的图形

                    if (_Value > ThresholdWarnning)
                    {
                        blend.Positions = _FullNormalGradientPosition;
                        blend.Colors = _InnerColorNormal;
                    }
                    else if (_Value > ThresholdAlarm)
                    {
                        blend.Positions = _FullWarnningGradientPosition;
                        blend.Colors = _InnerColorWarnning;
                    }
                    else
                    {
                        blend.Positions = _FullAlarmGradientPosition;
                        blend.Colors = _InnerColorAlarm;
                    }

                    lgb.InterpolationColors = blend;
                    g.FillRectangle(lgb, new RectangleF(0f, height - (height - _CapHeight) * Value / 100f, width, (height - _CapHeight) * Value / 100f));

                    g.DrawLines(new Pen(_BorderColor, 2f), borderPoints);
                }
            }
            //bmp.Save(@"c:\a.bmp");
            return bmp;
        }

//         public int angle
//         {
//             get;
//             set;
//         }

        protected override void OnPaint(PaintEventArgs pe)
        {

            using (Bitmap bmp = new Bitmap(this.Width, this.Height))
            {
                using (Graphics g = Graphics.FromImage(bmp))
                {
                    g.SmoothingMode = SmoothingMode.AntiAlias;
                    g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
                    //g.Clear(Color.Yellow);
                    if (Orientation == Orientation.Horizontal)
                    {
                        //g.RotateTransform(angle);
                        g.TranslateTransform(this.Width, 0);
                        g.RotateTransform(90);
                        
                        //g.DrawImage(_EmptyBattery, 0, 0);
                        g.DrawImage(DrawEmptyBattery(this.Height, this.Width), 0, 0);
                    }
                    else
                    {
                        //g.DrawImage(_EmptyBattery, 0, 0);
                        g.DrawImage(DrawEmptyBattery(this.Width, this.Height), 0, 0);
                    }
                    g.ResetTransform();

                    SizeF fontSize = g.MeasureString(this.Value.ToString() + "%", this.Font);

                    g.DrawString(this.Value.ToString() + "%", this.Font, new SolidBrush(this.ForeColor), (this.Width - fontSize.Width) / 2f, (this.Height - fontSize.Height) / 2f);

                }
                pe.Graphics.DrawImage(bmp, 0, 0);
            }

            base.OnPaint(pe);
        }
    }
}
